/* cl.ext.parsley 0.1*/
(
    function (factory) {
        if (typeof define === 'function' && define.amd) {
            define(['jquery',"moment","Parsley"], function($,momentjs) {
                factory($,momentjs);
            });
        } else if (typeof module === 'object' && module.exports) {
            var momentjs = require('moment');
            var parsleyjs = require('Parsley');
            module.exports = function( root, jQuery ) {
                if ( jQuery === undefined ) {
                    if ( typeof window !== 'undefined' ) {
                        jQuery = require('jquery');
                    }
                    else {
                        jQuery = require('jquery')(root);
                    }
                }
                factory(jQuery,momentjs,parsleyjs);
            };
        } else {
            factory(jQuery,moment);
        }
    }(
    function ($,moment){
        var defaults={errStyle:"icon"}; //errStyle(icon|lower|selftip)
        var defaultsMsg={
            defaultMessage: "不正确的值",
            type: {
                email:        "请输入一个有效的电子邮箱地址",
                url:          "请输入一个有效的链接",
                number:       "请输入正确的数字",
                integer:      "请输入正确的整数",
                digits:       "请输入正确的号码",
                alphanum:     "请输入字母或数字"
            },
            notblank:       "请输入值",
            required:       "此项不能为空",
            pattern:        "格式不正确",
            min:            "输入值请大于或等于 %s",
            max:            "输入值请小于或等于 %s",
            range:          "输入值应该在 %s 到 %s 之间",
            minlength:      "请输入至少 %s 个字符",
            maxlength:      "请输入至多 %s 个字符",
            length:         "字符长度应该在 %s 到 %s 之间",
            mincheck:       "请至少选择 %s 个选项",
            maxcheck:       "请选择不超过 %s 个选项",
            check:          "请选择 %s 到 %s 个选项",
            equalto:        "两次输入值不同"
        };
        var $modalCommon={
            getDefaults :function () {
                return defaults
            },
            getOptions : function (elementData,options) {
                options=$.ExtCommon.isCheckEmpty(options)?{}:options;
                var optionBase =$.ExtCommon.initMergeJson(elementData,options);
                optionBase =$.ExtCommon.initMergeJson(this.getDefaults(),optionBase);
                return optionBase
            },
            checkSpecialElement:{
                required:function(element,options){
                    var value=element.data("initValue");
                    var isSuccess=!$.ExtCommon.isCheckEmpty(value);
                    if(isSuccess){
                        $modalCommon.checkSuccess(element);
                    }else{
                        element.addClass("parsley-error");
                        $modalCommon.error(element,[defaultsMsg.required],options);
                    }
                    return isSuccess
                }
            },
            checkSuccess:function(element){
                element.removeClass("parsley-error");
                var parent=element.parent();
                if(parent.hasClass("parsley-parent")){parent.removeClass("parsley-parent-error")}

                var arrCircle=parent.find(".fa-exclamation-circle");
                if(arrCircle.length>0){arrCircle.tooltip('destroy').empty().remove()}
                var arrLower=parent.find(".parsley-error-msglower");
                if(arrLower.length>0){arrLower.empty().remove()}
                var arrSelftip=parent.find(".parsley-error-selftip");
                if(arrSelftip.length===1){
                    var tempSelfTipEl= $.ExtCommon.isCheckUndefined(arrSelftip.first().data("parsleyPlaceSelftipParent"))?element:parent;
                    tempSelfTipEl.tooltip('destroy');
                }
            },
            error:function(element,arrMsg,options){
                var parent=element.parent();
                var tempHtmlErrMsg="";
                switch(options.errStyle){
                    case "lower":
                        parent.find(".parsley-error-msglower").empty().remove();
                        tempHtmlErrMsg='<div class="parsley-error-msglower">'+(typeof arrMsg==="string"?arrMsg:arrMsg.join("；"))+'</div>';
                        break;
                    case "icon":
                        parent.find(".fa-exclamation-circle").tooltip('destroy').empty().remove();
                        tempHtmlErrMsg='<i class="parsley-error-icon fa fa-exclamation-circle" data-toggle="tooltip" data-placement="left"></i>';
                        break;
                    case "selftip":
                        element.addClass("parsley-error-selftip");
                        break
                }
                if(tempHtmlErrMsg.length>0){
                    var parsleyPlace=element.data("parsleyPlace");
                    if(parsleyPlace){
                        var temp=parsleyPlace.split("|");
                        switch(temp[0]){
                            case "before":
                                $(temp[1]).before(tempHtmlErrMsg);
                                break;
                            case "after":
                                $(temp[1]).after(tempHtmlErrMsg);
                                break;
                        }
                    }else{
                        parent.append(tempHtmlErrMsg);
                    }
                }
                if(parent.hasClass("parsley-parent")){parent.addClass("parsley-parent-error")}
                var tipTitle=typeof arrMsg==="string"?arrMsg:arrMsg.join("<br />");
                switch(options.errStyle){
                    case "icon":
                        parent.find(".fa-exclamation-circle").tooltip({container:"body","placement":"right","html": true, "title": tipTitle});
                        break;
                    case "selftip":
                        var tempSelfTipEl= $.ExtCommon.isCheckUndefined(element.data("parsleyPlaceSelftipParent"))?element:parent;
                        if(tempSelfTipEl.data("bs.tooltip")){
                            tempSelfTipEl.attr("data-original-title",tipTitle)
                        }else{
                            tempSelfTipEl.tooltip({container:"body","placement":"top",trigger:"hover","html": true,"title": tipTitle});
                        }
                        break;
                }
            }
        };
        var ParsleyExtModal = function(element, options) {
            var self=this;
            self.isStartParsley=false;
            self.element = $(element);
            self.optionBase=$modalCommon.getOptions(self.element.data(),options);
            self.element.addClass("form-parsley-style-"+self.optionBase.errStyle);
            self._initParsley(self.element);
            this.bindSpecialEvent();
        };
        ParsleyExtModal.prototype = {
            bindSpecialEvent:function(element){
                var self=this;
                var newEl= $.ExtCommon.isCheckUndefined(element)?this.element:this.element.find(element);
                newEl.find("[data-parsley-specialEvent]").each(function(){
                    var _this=$(this);
                    if(_this.hasClass("parsley-done-specialEvent")){}
                    else{
                        _this.addClass("parsley-done-specialEvent");
                        var event=_this.attr("data-parsley-specialEvent");
                        _this.on(event,function(){
                            self.validate($(this))
                        });

                    }
                });
            },
            _checkSpecialElement:function(_this){
                var operate=_this.attr("data-parsley-specialElement");
                return !$.ExtCommon.isCheckEmpty(operate)&& $modalCommon.checkSpecialElement[operate]?$modalCommon.checkSpecialElement[operate](_this,this.optionBase):true;
            },
            validateSpecialElementAll:function(){
                var b=true;
                var self=this;
                self.element.find("[data-parsley-specialElement]").each(function(){
                    var _this=$(this);
                    var isCheck=self._checkSpecialElement(_this);
                    if(!isCheck){b=false;}
                });
                return b
            },
            validate:function(parsleyObj,isLiberty) {
                isLiberty= $.ExtCommon.isCheckUndefined(isLiberty)?false:isLiberty;
                var b=true;
                var self=this;
                if($.ExtCommon.isCheckEmpty(parsleyObj)){
                    self.reset();
                    self.isStartParsley=true;
                    var c1=self.element.parsley().validate();
                    var c2=self.validateSpecialElementAll();
                    b=c1&&c2;
                }else{
                    var element=$.ExtCommon.isCheckString(parsleyObj)?$(parsleyObj):parsleyObj;
                    if(self.element.find(element).length>0){
                        if(self.isStartParsley || isLiberty){
                            element.each(function(){
                                var _this=$(this);
                                //var thisObj=self._initParsley(_this);
                                //var tv=thisObj.validate();
                                var tv=_this.parsley().validate();
                                var tempB=self._checkSpecialElement(_this) && typeof tv==="boolean" && tv;
                                if(!tempB){b=false}
                            });
                        }
                    }else{
                        b=false
                    }
                }
                return b
            },
            _initParsley:function(element){
                var self=this;
                return element.parsley()
                    .on('field:error', function(e) {
                        var _this=e.$element;
                        var arrMsg=$.map(e.validationResult,function(info){
                            var errmsg=_this.attr("data-parsley-"+info.assert.name+"-message");
                            return $.ExtCommon.isCheckEmpty(errmsg)?window.Parsley.getErrorMessage(info.assert):errmsg;
                        });
                        $modalCommon.error(_this,arrMsg,self.optionBase);
                    })
                    .on('field:success', function(e) {
                        $modalCommon.checkSuccess(e.$element)
                    })
                    .on('form:submit', function() {
                        return false;
                    });
            },
            reset:function(start){
                this.isStartParsley= start && typeof start==="boolean" ?start:false;
                this.element.parsley().reset();
                //this.element.find(".parsley-error-icon").empty().remove();
                $modalCommon.checkSuccess(this.element);
            },
            setExtSourceErrMsg:function (element,errMsg) {
                $modalCommon.error(element,errMsg,this.optionBase);
            },
            setExtSourceSuccess:function (element) {
                $modalCommon.checkSuccess(element);
            },
            refresh:function(){
            }
        };

        $.fn.ExtParsley = function(options) {
            var dataFun;
            this.each(function() {
                var el = $(this);
                if(el.is("form")) {
                    if (el.data('ExtParsley')) {
                        if (typeof  options === "string") {
                            if (el.data('ExtParsley')[options]) {
                                dataFun = el.data('ExtParsley')[options]()
                            } else {
                                dataFun = el.data('ExtParsley')
                            }
                        } else {
                            dataFun = el.data('ExtParsley')
                        }
                    } else {
                        dataFun = new ParsleyExtModal(el, options);
                        el.data('ExtParsley', dataFun);
                    }
                }
            });
            return dataFun;
        };
        var parsleComm={
            getByteLen:function(str){
                var len = 0;
                for (var i = 0; i < str.length; i++) {
                    var si = str.charAt(i);
                    if (si.match(/[^\x00-\xff]/ig) !== null) {
                        len += 3;
                    }
                    else {
                        len += 1;
                    }
                }
                return len;
            }
        };
        var parsleyValidatorAdd=function(){
            window.Parsley.addValidator('numMultiple', {
                validateString: function(value, num) {
                    num= $.ExtCommon.isCheckEmpty(num)?100:parseInt(num);
                    value=$.trim(value.removesplit());
                    if(value.length>0){
                        value=parseInt(value);
                        return value%num===0
                    }else{
                        return true;
                    }
                },
                messages: {
                    "zh-cn":"数字必须为百的整数倍"
                }
            });
            window.Parsley.addValidator('minGreater', {
                validateString: function(value, requirement) {
                    value=$.trim(value.removesplit());
                    if(value.length>0){
                        return  parseFloat(value)>parseFloat(requirement);
                    }else{
                        return true;
                    }
                },
                messages: {
                    "zh-cn":"输入值请大于 %s"
                }
            });
            window.Parsley.addValidator('minGreaterEqual', {
                validateString: function(value, requirement) {
                    value=$.trim(value.removesplit());
                    if(value.length>0){
                        return  parseFloat(value)>=parseFloat(requirement);
                    }else{
                        return true;
                    }
                },
                messages: {
                    "zh-cn":"输入值不能小于 %s"
                }
            });
            window.Parsley.addValidator('maxGreater', {
                validateString: function(value, requirement) {
                    value=$.trim(value.removesplit());
                    if(value.length>0){
                        return  parseFloat(value)<=parseFloat(requirement);
                    }else{
                        return true;
                    }
                },
                messages: {
                    "zh-cn":"输入值请小于等于 %s"
                }
            });
            window.Parsley.addValidator('stringlenmax', {
                validateString: function(value, requirement) {
                    var len=parsleComm.getByteLen(value);
                    return len<=parseInt(requirement);
                },
                messages: {
                    "zh-cn":"长度不能超过%s个字节"
                }
            });
            window.Parsley.addValidator('stringlenmin', {
                validateString: function(value, requirement) {
                    var len=parsleComm.getByteLen(value);
                    return len>=parseInt(requirement);
                },
                messages: {
                    "zh-cn":"长度不能小于%s个字节"
                }
            });
            window.Parsley.addValidator('numrange', {
                requirementType: ['integer', 'integer'],
                validateString: function(value, min,max) {
                    var valueF=parseFloat(value.replace(/,/g, ''));
                    return valueF>=parseFloat(min) && valueF<=parseFloat(max);
                },
                messages: {
                    "zh-cn":"输入值应该在 %s 到 %s 之间"
                }
            });
            window.Parsley.addValidator('beforeBalance', {
                validateString: function(value, requirement) {
                    var balance = $(requirement).text().removesplit(",");
                    var valueF = parseFloat(value.removesplit(","));
                    return valueF <= balance;
                },
                messages: {
                    "zh-cn":"转账金额不能大于账户余额"
                }
            });
            window.Parsley.addValidator('afterNow', {
                validateString: function(value) {
                    return moment(value).diff(moment().format("YYYY-MM-DD"))>=0;
                },
                messages: {
                    "zh-cn":"该时间不能小于当前时间"
                }
            });
            window.Parsley.addValidator('beforeEndtime', {
                validateString: function(value, requirement) {
                    var timeValue=$(requirement).val();
                    if(timeValue.length>0){
                        return moment(value).diff(moment($(requirement).val()).format("YYYY-MM-DD"))<=0;
                    }else{
                        return true;
                    }
                },
                messages: {
                    "zh-cn":"该时间不能大于结束时间"
                }
            });
            window.Parsley.addValidator('afterStarttime', {
                requirementType: 'string',
                validateString: function(value, requirement) {
                    var _this=$(requirement);
                    var timeValue=_this.is("input")?_this.val():$.trim(_this.text());
                    if(timeValue.length>0){
                        return moment(value).diff(moment(timeValue).format("YYYY-MM-DD"))>=0;
                    }else{
                        return true;
                    }
                },
                messages: {
                    "zh-cn":"该时间不能小于开始时间"
                }
            });
            window.Parsley.addValidator('phone', {
                requirementType: 'string',
                validateString: function(value) {
                    value=$.trim(value);
                    if(value.length>0){
                        return (/^1\d{10}$/).test(value);
                    }else{
                        return true;
                    }
                },
                messages: {
                    "zh-cn":"手机号不正确"
                }
            });
            window.Parsley.addValidator('telephone', {
                requirementType: 'string',
                validateString: function(value) {
                    value=$.trim(value);
                    if(value.length>0){
                        return (/^\d{3,4}-\d{6,8}$/).test(value);
                    }else{
                        return true;
                    }
                },
                messages: {
                    "zh-cn":"固定电话格式不正确,格式为：区号-座机号"
                }
            });
            window.Parsley.addValidator('qq', {
                requirementType: 'string',
                validateString: function(value) {
                    value=$.trim(value);
                    if(value.length>0){
                        return (/^\d{5,10}$/).test(value);
                    }else{
                        return true;
                    }
                },
                messages: {
                    "zh-cn":"QQ号不正确"
                }
            });
            window.Parsley.addValidator('identity', {
                requirementType: 'string',
                validateString: function(value) {
                    value=$.trim(value);
                    if(value.length>0){
                        return (/(^\d{18}$)|(^\d{17}(\d|X|x)$)/).test(value);
                    }else{
                        return true;
                    }
                },
                messages: {
                    "zh-cn":"身份证号不正确"
                }
            });
            window.Parsley.addValidator('numletter', {
                requirementType: 'string',
                validateString: function(value) {
                    value=$.trim(value);
                    if(value.length>0){
                        return (/^[0-9a-zA-Z]+$/).test(value);
                    }else{
                        return true;
                    }
                },
                messages: {
                    "zh-cn":"只能输入英文或者数字"
                }
            });
            window.Parsley.addValidator('urlhttp', {
                requirementType: 'string',
                validateString: function(value) {
                    value= $.trim(value);
                    if(value.length>0){
                        //var regurl=new RegExp("^(http|https)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&amp;%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&amp;%\$#\=~_\-]+))*$", 'g');
                        var regUrl=new RegExp("^(http|https)\://.+?$", 'g');
                        return regUrl.test(value);
                    }else{
                        return true;
                    }
                },
                messages: {
                    "zh-cn":"Url格式不正确"
                }
            });
            window.Parsley.addValidator('urlhttpGdt', {
                requirementType: 'string',
                validateString: function(value) {
                    value= $.trim(value);
                    if(value.length>0){
                        var temp=value.match(/^(\w+:\/\/)?([^\/]+)/);
                        if(temp.length>=3){
                            var h=temp[2];
                            if(h.indexOf(":")>-1){
                                return false;
                            }else{
                                var li=h.lastIndexOf(".");
                                if(li>-1){
                                    var l=h.substr(h.lastIndexOf(".")+1);
                                    if(l.length>=2&&l.length<=4){
                                        return /^[A-Za-z]+?$/.test(l);
                                    }else{
                                        return false;
                                    }
                                }else{
                                    return false;
                                }
                            }
                        }else{
                            return false;
                        }
                    }else{
                        return true;
                    }
                },
                messages: {
                    "zh-cn":"Url格式不正确"
                }
            });
            window.Parsley.addValidator('illegalValue', {
                validateString: function(value) {
                    value= $.trim(value);
                    if(value.length>0){
                        return value.indexOf("/")===-1 && value.indexOf("\\")===-1
                    }else{
                        return true;
                    }
                },
                messages: {
                    "zh-cn":"包含非法字符( \\ /)"
                }
            });
        };
        parsleyValidatorAdd();
        window.Parsley.addMessages('zh-cn', defaultsMsg);
        window.Parsley.setLocale('zh-cn');
        return ParsleyExtModal;
    })
);
